package com.anrongtec.zcpt.openapi.manager;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.anrongtec.zcpt.openapi.interfaces.ShuJuInterface;
import com.anrongtec.zcpt.openapi.interfaces.ShuJuURL;
import com.anrongtec.zcpt.openapi.model.AccessTokenInfo;
import com.anrongtec.zcpt.openapi.model.JsonDataResult;
import com.anrongtec.zcpt.openapi.model.Staff;
import com.anrongtec.zcpt.openapi.model.Token;
import com.anrongtec.zcpt.openapi.util.JSONHelper;
import com.anrongtec.zcpt.openapi.util.Util;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.ref.WeakReference;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

/**
 * UAHandler处理
 *
 * @author dongtianhao
 */
public class UAHandler extends Handler {
    private static final String MDM_PKG_NAME = "com.ansec.mdm";
    private static final int MSG_CHECK_UA = 1000; // 检测应用权限，并连接终端安全管控获取用户信息
    private static final int MSG_DECODE_RESULT = 2000; // 检测应用权限，并连接终端安全管控获取用户信息
    private static final int MSG_REFRESH_TOKEN = 3000; // 刷新TOKEN
    private static final int MSG_GET_STAFF_INFO = 4000; // 获取用户信息
    private static final int MSG_SWITCH_LOGIN = 5000; // 切换用户
    private IAuthCallBack authCallBack;
    private String appKey;
    private ShuJuInterface dInterface;
    private Context context;
    private String token;
    private String accessToken;// 每次传递AccessToken 都会重置
    private Handler mHandler;// 与Activity交互的handler
    private Looper looper;
    private WeakReference<Activity> weakReference; // 统一认证登录的弱引用
    private WeakReference<Activity> switchWeakReference; // 切换登录的弱引用
    private String mPackageName;//包名

    private void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    private UAHandler() {
    }

    public UAHandler(Looper looper) {
        super(looper);
        this.looper = looper;
    }

    void init(Context context, String appKey) {
        this.appKey = appKey;
        this.context = context;
        dInterface = new ShuJuInterface(context);
    }

    void setCurrentActivity(WeakReference<Activity> weakReference) {
        initMainHandler(weakReference);
    }

    void setAuthCallBack(IAuthCallBack authCallBack) {
        this.authCallBack = authCallBack;
    }

    private void initMainHandler(WeakReference<Activity> weakReference) {
        mHandler = new Handler(weakReference.get().getMainLooper()) {
            int what;

            @Override
            public void handleMessage(Message msg) {
                what = msg.what;
                switch (what) {
                    case 1001:
                        authCallBack.onError(1001, msg.obj + "");
                        break;
                    case 999:
                        authCallBack.onError(999, "连接认证服务器异常");
                        break;
                    case 998:
                        authCallBack.onError(998, "获取应用权限失败");
                        break;
                    case 997:
                        authCallBack.onError(997, "应用权限异常");
                        break;
                    case 996:
                        authCallBack.onError(996, "终端安全管控未安装，请先安装终端安全管控");
                        break;
                    case 995:
                        authCallBack.onError(995, "连接终端安全管控失败");
                        break;
                    case 994:
                        authCallBack.onError(994, "SDK尚未初始化");
                        break;
                    case 992:
                        authCallBack.onError(992, "无用户认证信息");
                        break;
                    case 990:
                        authCallBack.onError(990, "认证取消");
                        break;
                    case 987:
                        authCallBack.onError(987, "APPKEY为空");
                        break;
                    // case 101:
                    // authCallBack.onAppAuthResult(token);
                    // break;
                    case 100:
                        AccessTokenInfo info = (AccessTokenInfo) msg.obj;
                        setAccessToken(info.getAccessToken());
//                        Log.e("uaManager", info.toString() + " result");
                        authCallBack.onSuccess(info);
                        break;
                }
            }
        };
    }

    /**
     * 用户认证
     *
     * @param authCallBack
     * @param weakReference
     */
    public void authLogin(final IAuthCallBack authCallBack, String mPackageName, WeakReference<Activity> weakReference) {
        this.weakReference = weakReference;
        this.authCallBack = authCallBack;
        if (mHandler == null) {
            initMainHandler(weakReference);
        }
//        LogUtil.e("pkgName1" + mPackageName);
        this.mPackageName = mPackageName;
        sendEmptyMessage(MSG_CHECK_UA);
    }

    public void authLogin(final IAuthCallBack authCallBack, Activity activity) {
        this.weakReference = new WeakReference<Activity>(activity);
        this.authCallBack = authCallBack;
        if (mHandler == null) {
            initMainHandler(weakReference);
        }
        sendEmptyMessage(MSG_CHECK_UA);
    }

    /**
     * 检查应用权限
     */
    private void checkAppAuth(boolean isSwitchUser, String mPackageName) {
        if (context == null) {
            mHandler.sendEmptyMessage(994);
            return;
        }
        // appkey为空
        if (TextUtils.isEmpty(appKey)) {
            mHandler.sendEmptyMessage(987);
            return;
        }
        authCallBack.onProgress("正在获取应用授权");
        String json = "";
        // 如果是切换用户
        if (!isSwitchUser) {
//            json = dInterface.checkAppAuth(appKey, accessToken, mPackageName);
            json = dInterface.checkAppAuth(appKey, mPackageName);
            if (TextUtils.isEmpty(json)) {
                mHandler.sendEmptyMessage(999);
                return;
            }
            // 判断json内容，是否具备统一认证权限
            final JsonDataResult<Token> result = JSONHelper.parseInfoFromJson(json, new TypeToken<JsonDataResult<Token>>() {
            }.getType());
            token = result.getData().getToken();
            if (result == null) {
                mHandler.sendEmptyMessage(998);
                return;
            }
            if (!ShuJuURL.RetCode.SUCCESS.equals(result.getRetCode())) {
                mHandler.sendEmptyMessage(997);
                return;
            } else {
                if (null != result.getData()) {
                    token = result.getData().getToken();
                    // mHandler.sendEmptyMessage(101);
                } else {
                    mHandler.sendEmptyMessage(997);
                    return;
                }
            }
        }
        // 是否能够绑定MDM提供的service
        authCallBack.onProgress("正在连接终端安全管控终端");
        if (!Util.isAppInstalled(context.getApplicationContext(), MDM_PKG_NAME)) {
            mHandler.sendEmptyMessage(996);
            return;
        }
        try {
            Intent intent = new Intent("com.ansec.mdm.action.login");
            intent.putExtra("is_switch_user", isSwitchUser);
            intent.putExtra("pkgName", mPackageName);
//            LogUtil.e("pkgName" + mPackageName);
            weakReference.get().startActivityForResult(intent, 100);
        } catch (Exception e) {
            e.printStackTrace();
            mHandler.sendEmptyMessage(995);
        }
    }

    /**
     * 此方法与下面方法，方法名称相同，只有参数顺序不同，切忌弄混，只是为了在子线程处理事务
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    //TODO  此处
    void decodeResult(int requestCode, int resultCode, Intent data) {
        Message msg = Message.obtain();
        msg.arg1 = requestCode;
        msg.arg2 = resultCode;
        msg.obj = data;
        msg.what = MSG_DECODE_RESULT;
        sendMessage(msg);
    }

    /**
     * 处理从用户登录页面返回
     */
    private void decodeResult(Intent data, int requestCode, int resultCode) {
        // 不属于调用用户界面的启动
        if (requestCode != 100) {
            return;
        }
        // 从用户界面取消认证
        if (resultCode != Activity.RESULT_OK) {
            mHandler.sendEmptyMessage(990);
            return;
        }
        authCallBack.onProgress("正在认证用户...");
        String res = data.getStringExtra("key_result");
        // 返回信息为空，判定为用户认证取消
        if (TextUtils.isEmpty(res)) {
            mHandler.sendEmptyMessage(990);
            return;
        }
        final String str_result_json = decrypt(res, "res+%&*e");
        // 没有解析出来用户信息，判定为无用户认证信息
        if (TextUtils.isEmpty(str_result_json)) {
            mHandler.sendEmptyMessage(992);
            return;
        }
        String idno = JSONHelper.getStringByKeyFromJson("identity", str_result_json);
        String staffName = JSONHelper.getStringByKeyFromJson("nick_name", str_result_json);
        String dept_name = JSONHelper.getStringByKeyFromJson("dept_name", str_result_json);
        String tfCa = JSONHelper.getStringByKeyFromJson("tf_ca", str_result_json);
        String tfNumber = JSONHelper.getStringByKeyFromJson("tf_number", str_result_json);
        String seclevel = JSONHelper.getStringByKeyFromJson("seclevel", str_result_json);
        String imei = JSONHelper.getStringByKeyFromJson("imei", str_result_json);
        String uid = JSONHelper.getStringByKeyFromJson("uid", str_result_json);
        String uuid = JSONHelper.getStringByKeyFromJson("uuid", str_result_json);
        final String json = dInterface.getRefeshAccessToken(mPackageName, appKey, token, idno);
        final JsonDataResult<AccessTokenInfo> result = JSONHelper.parseInfoFromJson(json,
                new TypeToken<JsonDataResult<AccessTokenInfo>>() {
                }.getType());
        if (result == null) {
            mHandler.sendEmptyMessage(992);
            return;
        }
        // 服务器返回异常
        if (!ShuJuURL.RetCode.SUCCESS.equals(result.getRetCode())) {
            Message msg = new Message();
            msg.obj = result.getRetMsg();
            msg.what = 1001;
            mHandler.sendMessage(msg);
            return;
        }
        Log.d("ua", "result: 都没事 认证成功；");
        // 都没事 认证成功；
        Message msg = new Message();
        AccessTokenInfo info = result.getData();
        accessToken = info.getAccessToken();
        if (TextUtils.isEmpty(dept_name)){
            dept_name = "";
        }
        info.setDeptName(dept_name);
        if (TextUtils.isEmpty(tfCa)){
            tfCa = "";
        }
        info.setTfCa(tfCa);
        if (TextUtils.isEmpty(tfNumber)){
            tfNumber = "";
        }
        info.setTfNumber(tfNumber);
        if (TextUtils.isEmpty(idno)){
            idno = "";
        }
        info.setIdno(idno);
        if (TextUtils.isEmpty(staffName)){
            staffName = "";
        }
        info.setStaffName(staffName);
        if (TextUtils.isEmpty(seclevel)){
            seclevel = "";
        }
        info.setNetType(seclevel);
        if (TextUtils.isEmpty(uid)){
            uid = "";
        }
        info.setUid(uid);
        info.setImei(imei);
        if (TextUtils.isEmpty(uuid)){
            uuid = "";
        }
        info.setUuid(uuid);
        msg.obj = info;
        msg.what = 100;
        mHandler.sendMessage(msg);
    }

    void getStaffInfo(final String accessToken, final OperationCallBack callBack) {
        setAccessToken(accessToken);
        Message msg = new Message();
        msg.obj = callBack;
        msg.what = MSG_GET_STAFF_INFO;
        sendMessage(msg);
    }

    /**
     * 获取用户信息
     *
     * @param accessToken
     * @param callBack
     */
    private void getStaffInfo(final OperationCallBack callBack, final String accessToken) {
        String json = dInterface.getStaffInfo(accessToken);
        if (TextUtils.isEmpty(json)) {
            callBack.onError(IAuthCallBack.ERROR_SERVER, "服务器异常");
            return;
        }
        // 判断json内容，是否具备统一认证权限
        JsonDataResult<Staff> result = JSONHelper.parseInfoFromJson(json, new TypeToken<JsonDataResult<Staff>>() {
        }.getType());
        if (result == null) {
            callBack.onError(989, "获取用户信息失败");
            return;
        }
        if (!ShuJuURL.RetCode.SUCCESS.equals(result.getRetCode())) {
            callBack.onError(989, result.getRetMsg());
            return;
        } else {
            Staff staff = result.getData();
            callBack.onSuccess(new Gson().toJson(staff));
        }
    }

    void refreshToken(final String accessToken, final OperationCallBack callback) {
        setAccessToken(accessToken);
        Message msg = new Message();
        msg.what = MSG_REFRESH_TOKEN;
        msg.obj = callback;
        sendMessage(msg);
    }

    /**
     * 刷新Token
     */
    private void refreshToken(final OperationCallBack callback) {
        String json = dInterface.checkAppAuth(appKey, accessToken);
        if (TextUtils.isEmpty(json)) {
            callback.onError(993, "令牌刷新失败");
            return;
        }
        // 判断json内容，是否具备统一认证权限
        JsonDataResult<Token> result = JSONHelper.parseInfoFromJson(json, new TypeToken<JsonDataResult<Token>>() {
        }.getType());
        if (result == null) {
            callback.onError(993, json);
            return;
        }
        if (!ShuJuURL.RetCode.SUCCESS.equals(result.getRetCode())) {
            callback.onError(993, result.getRetMsg());
            return;
        } else {
            callback.onSuccess(json);
        }
    }

    /**
     * 切换用户
     *
     * @param accessToken
     * @param activity
     * @param authCallBack
     */
    void switchLogin(final String accessToken, String pkgName ,final Activity activity, final IAuthCallBack authCallBack) {
        setAccessToken(accessToken);
        weakReference = new WeakReference<Activity>(activity);
        this.authCallBack = authCallBack;
        // Message msg = Message.obtain();
        // msg.obj = authCallBack;
        if (mHandler == null) {
            initMainHandler(weakReference);
        }
        this.mPackageName = pkgName;
        sendEmptyMessage(MSG_SWITCH_LOGIN);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            // 应用认证
            case MSG_CHECK_UA:
                checkAppAuth(false, mPackageName);
                break;
            // 处理返回结果
            case MSG_DECODE_RESULT:
                decodeResult((Intent) msg.obj, msg.arg1, msg.arg2);
                break;
            // 刷新TOKEN；
            case MSG_REFRESH_TOKEN:
                refreshToken((OperationCallBack) msg.obj);
                break;
            // 获取用户信息
            case MSG_GET_STAFF_INFO:
                getStaffInfo((OperationCallBack) msg.obj, accessToken);
                break;
            // 切换登录
            case MSG_SWITCH_LOGIN:
                checkAppAuth(true, mPackageName);
                break;
        }
    }

    /**
     * des 解密 padding为 PKCS5Padding
     *
     * @param message 密文
     * @param key     解密key
     * @return 解密后数据
     */
    private String decrypt(String message, String key) {
        try {
            if (message == null) {
                return null;
            }
            byte[] bytesrc = convertHexString(message);
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
            IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
            cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
            byte[] retByte = cipher.doFinal(bytesrc);
            return new String(retByte);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private byte[] convertHexString(String s) {
        byte digest[] = new byte[s.length() / 2];
        for (int i = 0; i < digest.length; i++) {
            String byteString = s.substring(2 * i, 2 * i + 2);
            int byteValue = Integer.parseInt(byteString, 16);
            digest[i] = (byte) byteValue;
        }
        return digest;
    }
}
